<template>
    <BaseComposite :config="config" :refreshEditor="refreshEditor" @updateData="updateData">
        <el-link href="https://gitee.com/renlin901017/rl-plus-docs/blob/master/docs/BaseForm.md" target="_blank" type="primary">更多用法请参考文档</el-link>
        <!-- 基础用法 -->
        <BaseItem label="基础用法" :text="BaseHtml+BaseScript">
            <BaseForm :config="BaseConfig" ref="BaseFormRef" @form="BaseFormChange">
                <template #blockslot>
                    <hr />
                    <p class="tip" style="background:#f5f5f5;color:#333;font-weight:bold;font-size:24px;">
                        blockslot
                    </p>
                    <hr />
                </template>
                <template #slot="{config}">
                    slot--{{config}}
                </template>
            </BaseForm>
        </BaseItem>
        <!-- 搜索用法 -->
        <BaseItem label="搜索用法" :text="SearchHtml+SearchScript">
            <BaseForm ref="SearchForm" :config="SearchConfig" @search="SearchFormChange"></BaseForm>
        </BaseItem>
        <!-- 其他用法 -->
        <BaseItem label="其他用法" :text="OtherHtml+OtherScript">
            <BaseForm ref="OtherForm" :config="OtherConfig">
                <!-- 基本信息 -->
                <template #BaseInfo="{config}">
                    {{config.label}}
                </template>
                <!-- 爱好 -->
                <template #hobby="{config}">
                    {{config.label}}
                </template>
                <!-- 家庭 -->
                 <template #family="{config}">
                    {{config.label}}
                </template>
                <div class="btns">
                    <BaseButton :config="btnConfig" @btnClick="btnClick" />
                </div>
            </BaseForm>
        </BaseItem>
        <!-- 自定义设置 -->
        <div class="item">
            <el-tooltip
                class="box-item"
                effect="dark"
                content="点击可复制"
                placement="top-start"
            >
                <p class="custom" @click="copyText(JsonToString(config))">自定义设置</p>     
            </el-tooltip>
            <BaseForm :key="config" :config="config"></BaseForm>
        </div>        
        <template #props>
            <BaseForm :config="formConfig" :key="formConfig" ref="myForm">                
                <div class="btns">                    
                    <el-button type="primary" @click="useConfig" :auto-insert-space="true">应用</el-button>
                    <el-button @click="reset" :auto-insert-space="true">重置</el-button>
                </div>
            </BaseForm>         
        </template>
    </BaseComposite>
</template>
<script lang="ts" setup>
import { ref, isRef, reactive, nextTick, computed } from 'vue';
import BaseComposite from '@/components/BaseComposite';
import BaseItem from '@/components/BaseItem';
import { ElButton, ElTooltip, ElLink} from "element-plus";
import dictJson from '@/assets/json';
import { BaseForm, BaseFormType, BaseFormItemEleType, GroupComsType, InputValue, BaseButton,BaseButtonType, BtnType, DatePickerType } from 'rl-plus';
import { deepClone, JsonToString } from 'rl-utils';
import { copyText } from '../../utils/index';
const data = [
    {label:"足球",value:"1"},
    {label:"排球",value:"2"},
    {label:"篮球",value:"3",disabled:true},
    {label:"羽毛球",value:"4"},
    {label:"乒乓球",value:"5"},
    {label:"网球",value:"6"},
]

// #region 基础用法
const BaseHtml = `  
<BaseForm :config="config" @form="BaseChange">
    <template #blockslot>
        <hr />
        <p class="tip" style="background:#f5f5f5;color:#333;font-weight:bold;font-size:24px;">
            blockslot
        </p>
        <hr />
    </template>
    <template #slot="{config}">
        slot--{{config}}
    </template>
</BaseForm>`
const BaseScript = `
import {reactive } from 'vue';
import { BaseForm,BaseFormType, BaseFormItemEleType, GroupComsType } from 'rl-plus';
const config = reactive<BaseFormType>({
    loading:false,//保存按钮loading
    eleType:GroupComsType.BASEFORM,
    config: [
        {label:"cascader",prop:"cascader",value:null,eleType:BaseFormItemEleType.BASECASCADER,data:data},
        {label:"checkbox",prop:"checkbox",value:[],eleType:BaseFormItemEleType.BASECHECKBOX,data:data},
        {label:"datepicker",prop:"datepicker",value:null,eleType:BaseFormItemEleType.BASEDATEPICKER},
        {label:"input",prop:"input",value:null,eleType:BaseFormItemEleType.BASEINPUT},
        {label:"inputnumber",prop:'inputnumber',value:null,eleType:BaseFormItemEleType.BASEINPUTNUMBER},
        {label:"radio",prop:"radio",value:null,eleType:BaseFormItemEleType.BASERADIO,data:data},
        {label:"rate",prop:"rate",value:null,eleType:BaseFormItemEleType.BASERATE},
        {label:"select",prop:"select",value:null,eleType:BaseFormItemEleType.BASESELECT,data},
        {label:"slider",prop:"slider",value:null,eleType:BaseFormItemEleType.BASESLIDER},
        {label:"switch",prop:"switch",value:null,eleType:BaseFormItemEleType.BASESWITCH},
        {label:"blockslot",prop:"blockslot",value:null,eleType:BaseFormItemEleType.BLOCKSLOT,slot:"blockslot"},
        {label:"slot",prop:"slot",value:null,eleType:BaseFormItemEleType.SLOT,slot:'slot'},
    ]
})
const BaseFormRef=ref(null)
const BaseFormChange = (e) => {
    setTimeout(() => {    
        // 方式一
        BaseConfig.loading = !BaseConfig.loading
        // 方式二
        // BaseFormRef.value.newLoading=false
     },1000)
}
`
const BaseConfig = reactive<BaseFormType>({
    loading:false,//保存按钮loading
    eleType: GroupComsType.BASEFORM,
    config: [
        {label:"cascader",prop:"cascader",value:null,eleType:BaseFormItemEleType.BASECASCADER,data:data},
        {label:"checkbox",prop:"checkbox",value:[],eleType:BaseFormItemEleType.BASECHECKBOX,data:data},
        {label:"datepicker",prop:"datepicker",value:null,eleType:BaseFormItemEleType.BASEDATEPICKER},
        {label:"input",prop:"input",value:null,eleType:BaseFormItemEleType.BASEINPUT},
        {label:"inputnumber",prop:'inputnumber',value:null,eleType:BaseFormItemEleType.BASEINPUTNUMBER},
        {label:"radio",prop:"radio",value:null,eleType:BaseFormItemEleType.BASERADIO,data:data},
        {label:"rate",prop:"rate",value:null,eleType:BaseFormItemEleType.BASERATE},
        {label:"select",prop:"select",value:null,eleType:BaseFormItemEleType.BASESELECT,data},
        {label:"slider",prop:"slider",value:null,eleType:BaseFormItemEleType.BASESLIDER},
        {label:"switch",prop:"switch",value:null,eleType:BaseFormItemEleType.BASESWITCH},
        {label:"blockslot",prop:"blockslot",value:null,eleType:BaseFormItemEleType.BLOCKSLOT,slot:"blockslot"},
        {label:"slot",prop:"slot",value:null,eleType:BaseFormItemEleType.SLOT,slot:'slot'},
    ]
})
const BaseFormRef=ref(null)
const BaseFormChange = (e) => {
    setTimeout(() => {    
        // 方式一
        BaseConfig.loading = !BaseConfig.loading
        // 方式二
        // BaseFormRef.value.newLoading=false
     },1000)
}
// #endregion

// #region 搜索用法
const SearchHtml = `
<BaseForm ref="SearchForm" :config="config" @search="SearchFormChange"></BaseForm>
`
const SearchScript = `
import {reactive } from 'vue';
import { BaseForm,BaseFormType, BaseFormItemEleType, GroupComsType } from 'rl-plus';
const config = reactive<BaseFormType>({
    eleType: GroupComsType.BASESEARCH,
    labelWidth:70,
    config: [
        {label:"cascader",prop:"cascader",value:null,eleType:BaseFormItemEleType.BASECASCADER,data:data,clearable:true,},
        {label:"datepicker",prop:"datepicker",value:null,eleType:BaseFormItemEleType.BASEDATEPICKER,},
        {label:"input",prop:"input",value:null,eleType:BaseFormItemEleType.BASEINPUT,},
        {label:"select",prop:"select",value:null,eleType:BaseFormItemEleType.BASESELECT,data,},
    ]
})
const SearchFormChange = (e) => {
    console.log(e)
}
`
const SearchForm = ref(null)
const SearchConfig=reactive<BaseFormType>({
    eleType: GroupComsType.BASESEARCH,
    labelWidth:70,
    config: [
        {label:"cascader",prop:"cascader",value:null,eleType:BaseFormItemEleType.BASECASCADER,data:data,clearable:true,},
        {label:"datepicker",prop:"datepicker",value:null,eleType:BaseFormItemEleType.BASEDATEPICKER,},
        {label:"input",prop:"input",value:null,eleType:BaseFormItemEleType.BASEINPUT,},
        {label:"select",prop:"select",value:null,eleType:BaseFormItemEleType.BASESELECT,data,},
    ]
})
const SearchFormChange = (e) => {
    console.log(e)
}
// #endregion

// #region 其他用法
const OtherHtml = `
<BaseForm ref="OtherForm" :config="config">
    <!-- 基本信息 -->
    <template #BaseInfo="{config}">
        {{config.label}}
    </template>
    <!-- 爱好 -->
    <template #hobby="{config}">
        {{config.label}}
    </template>
    <!-- 家庭 -->
        <template #family="{config}">
        {{config.label}}
    </template>
    <div class="btns">
        <BaseButton :config="btnConfig" @btnClick="btnClick" />
    </div>
</BaseForm>
`
const OtherScript = `
import {reactive } from 'vue';
import { BaseForm,BaseFormType, BaseFormItemEleType, GroupComsType,DatePickerType,InputValue } from 'rl-plus';
const OtherForm = ref(null)
// checkbox显示隐藏
const showMonth = computed(() => {     
    return !OtherForm.value?.newData?.year
})
// checkbox显示隐藏
const showDate = computed(() => {     
    return !OtherForm.value?.newData?.month
})
const config=reactive<BaseFormType>({
    eleType:GroupComsType.BASEFORM,
    rules: {
        name: [{required: true, message: "请填写姓名", validator(rule, value, callback) {
                if (value) {
                    callback()
                } else {
                    callback(new Error('请填写姓名'))
                }        
            }
        }],
      sex: [{required: true, validator(rule, value, callback) {
            if (value) { 
                callback()
            }
            callback(new Error('请选择性别'))
        }
      }]
    },
    config: [
        {label:"基本信息",prop:"",value:null,eleType:BaseFormItemEleType.BLOCKSLOT,slot:"BaseInfo",class:"custom-title"},
        { label: "姓名", prop: "name", value: null,placeholder:'请填写姓名',        rules: [{
            required: true, message: "请填写姓名", validator(rule, value, callback) {
                if (value) {
                    callback()
                } else {
                    callback(new Error('请填写姓名'))
                }  
       } }], maxlength: 10, eleType: BaseFormItemEleType.BASEINPUT, class: "custom-item", style: "color:red" },
        {
            label: "性别", prop: "sex", value: null,eleType: BaseFormItemEleType.BASERADIO, data: [
                {label:'男',value:'1'},
                {label:'女',value:'2'},
            ], class: "custom-item", style: "color:red"
        },
        { label: "出生年月日", prop: "year", value: null, eleType: BaseFormItemEleType.BASEDATEPICKER,type:DatePickerType.YEAR, class: "custom-item", style: "color:red" },
        {label:"",prop:"month",value:null,eleType:BaseFormItemEleType.BASEDATEPICKER,type:DatePickerType.MONTH,hidden:showMonth,class:"custom-item",style:"color:red"},
        {label:"",prop:"date",value:null,eleType:BaseFormItemEleType.BASEDATEPICKER,type:DatePickerType.DATE,hidden:showDate,class:"custom-item",style:"color:red"},
    
        { label: "爱好", prop: "", value: null, eleType: BaseFormItemEleType.BLOCKSLOT, slot: "hobby",class:"custom-title" },
        { label: "球类", prop: "ball", value: [], eleType: BaseFormItemEleType.BASECHECKBOX, data: data, class: "custom-item", style: "color:red" },
        {label:"最爱",prop:"faves",value:null,eleType:BaseFormItemEleType.BASERADIO,data:data,class:"custom-item",style:"color:red"},

        { label: "家庭信息", prop: "", value: null, eleType: BaseFormItemEleType.BLOCKSLOT, slot: "family", class: "custom-title" },
        { label: "家庭成员几人", prop: 'personNumber', value: null, eleType: BaseFormItemEleType.BASEINPUTNUMBER, class: "custom-item", style: "color:red" },
        { label: "房屋套数", prop: "houseNumber", value: null, eleType: BaseFormItemEleType.BASEINPUT,type:InputValue.INT, class: "custom-item", style: "color:red" },
        {
            label: "房屋类别", prop: "houseType", value: [], eleType: BaseFormItemEleType.BASECHECKBOX, data: [
                {label:"独栋别墅",value:"1"},
                {label:"联排别墅",value:"2"},
                {label:"洋房",value:"3"},
                {label:"大平层",value:"4"},
                {label:"海景房",value:"5"},
        ], class: "custom-item", style: "color:red" }
    ]
})
// 自定义按钮
const btnConfig:BaseButtonType[] = [
    {name:"保存",type:BtnType.PRIMARY},
    {name:"保存并继续",type:BtnType.PRIMARY},
    {name:"取消"},
]
const btnClick = (e) => { 
    if (OtherForm.value) {
        OtherForm.value.submitForm().then(res => {
            if (e.name==='保存并继续') { 
                OtherForm.value.resetForm()
            }
        })
        console.log(e, OtherForm.value?.newData)
    }
}
// css
:deep(.custom-title){
    line-height: 48px;
    background: #f8f9fa;
    font-size: 16px;
    font-weight: 400;
    color: #333;
    position: relative;
    padding-left: 16px;
    margin-bottom: 20px;
    &::before{
        content: "";
        position: absolute;
        width: 4px;
        height: 16px;
        background: #655eff;
        left: 6px;
        top: 16px;
    }
}
.btns{
    display: flex;
    justify-content: center;
}
`
const OtherForm = ref(null)
// checkbox显示隐藏
const showMonth = computed(() => {     
    return !OtherForm.value?.newData?.year
})
// checkbox显示隐藏
const showDate = computed(() => {     
    return !OtherForm.value?.newData?.month
})
const OtherConfig=reactive<BaseFormType>({
    eleType: GroupComsType.BASEFORM,
    rules: {
        name: [{required: true, message: "请填写姓名", validator(rule, value, callback) {
                if (value) {
                    callback()
                } else {
                    callback(new Error('请填写姓名'))
                }        
            }
        }],
      sex: [{required: true, validator(rule, value, callback) {
            if (value) { 
                callback()
            }
            callback(new Error('请选择性别'))
        }
      }]
    },
    config: [
        {label:"基本信息",prop:"",value:null,eleType:BaseFormItemEleType.BLOCKSLOT,slot:"BaseInfo",class:"custom-title"},
        { label: "姓名", prop: "name", value: null,placeholder:'请填写姓名',        rules: [{
            required: true, message: "请填写姓名", validator(rule, value, callback) {
                if (value) {
                    callback()
                } else {
                    callback(new Error('请填写姓名'))
                }  
       } }], maxlength: 10, eleType: BaseFormItemEleType.BASEINPUT, class: "custom-item", style: "color:red" },
        {
            label: "性别", prop: "sex", value: null,eleType: BaseFormItemEleType.BASERADIO, data: [
                {label:'男',value:'1'},
                {label:'女',value:'2'},
            ], class: "custom-item", style: "color:red"
        },
        { label: "出生年月日", prop: "year", value: null, eleType: BaseFormItemEleType.BASEDATEPICKER,type:DatePickerType.YEAR, class: "custom-item", style: "color:red" },
        {label:"",prop:"month",value:null,eleType:BaseFormItemEleType.BASEDATEPICKER,type:DatePickerType.MONTH,hidden:showMonth,class:"custom-item",style:"color:red"},
        {label:"",prop:"date",value:null,eleType:BaseFormItemEleType.BASEDATEPICKER,type:DatePickerType.DATE,hidden:showDate,class:"custom-item",style:"color:red"},
    
        { label: "爱好", prop: "", value: null, eleType: BaseFormItemEleType.BLOCKSLOT, slot: "hobby",class:"custom-title" },
        { label: "球类", prop: "ball", value: [], eleType: BaseFormItemEleType.BASECHECKBOX, data: data, class: "custom-item", style: "color:red" },
        {label:"最爱",prop:"faves",value:null,eleType:BaseFormItemEleType.BASERADIO,data:data,class:"custom-item",style:"color:red"},

        { label: "家庭信息", prop: "", value: null, eleType: BaseFormItemEleType.BLOCKSLOT, slot: "family", class: "custom-title" },
        { label: "家庭成员几人", prop: 'personNumber', value: null, eleType: BaseFormItemEleType.BASEINPUTNUMBER, class: "custom-item", style: "color:red" },
        { label: "房屋套数", prop: "houseNumber", value: null, eleType: BaseFormItemEleType.BASEINPUT,type:InputValue.INT, class: "custom-item", style: "color:red" },
        {
            label: "房屋类别", prop: "houseType", value: [], eleType: BaseFormItemEleType.BASECHECKBOX, data: [
                {label:"独栋别墅",value:"1"},
                {label:"联排别墅",value:"2"},
                {label:"洋房",value:"3"},
                {label:"大平层",value:"4"},
                {label:"海景房",value:"5"},
        ], class: "custom-item", style: "color:red" }
    ]
})
// 自定义按钮
const btnConfig:BaseButtonType[] = [
    {name:"保存",type:BtnType.PRIMARY},
    {name:"保存并继续",type:BtnType.PRIMARY},
    {name:"取消"},
]
const btnClick = (e) => { 
    if (OtherForm.value) {
        OtherForm.value.submitForm().then(res => {
            if (e.name==='保存并继续') { 
                OtherForm.value.resetForm()
            }
        })
        console.log(e, OtherForm.value?.newData)
    }
}
// #endregion

// 初始化
const config = ref<BaseFormType>({
    eleType:GroupComsType.BASEFORM,
    config: [
        {label:"cascader",prop:"cascader",value:null,eleType:BaseFormItemEleType.BASECASCADER},
        {label:"checkbox",prop:"checkbox",value:[],eleType:BaseFormItemEleType.BASECHECKBOX,data},
        {label:"datepicker",prop:"datepicker",value:null,eleType:BaseFormItemEleType.BASEDATEPICKER},
        {label:"input",prop:"input",value:null,eleType:BaseFormItemEleType.BASEINPUT},
        {label:"inputnumber",prop:"inputnumber",value:null,eleType:BaseFormItemEleType.BASEINPUTNUMBER},
        {label:"radio",prop:"radio",value:null,eleType:BaseFormItemEleType.BASERADIO,data},
        {label:"rate",prop:"rate",value:null,eleType:BaseFormItemEleType.BASERATE},
        {label:"select",prop:"select",value:null,eleType:BaseFormItemEleType.BASESELECT,data},
        {label:"slider",prop:"slider",value:null,eleType:BaseFormItemEleType.BASESLIDER},
        {label:"switch",prop:"switch",value:null,eleType:BaseFormItemEleType.BASESWITCH},
    ]
})
// 备份数据
const initData = deepClone(config.value)
// 刷新JsonEditor
const refreshEditor = ref(true)
// form表单
const formConfig = reactive<BaseFormType>({
    eleType: GroupComsType.BASEFORM,
    labelWidth:300,
    config: [
        {
            eleType: BaseFormItemEleType.BASESWITCH,
            prop: 'inline',
            value:false,
            label: '行内表单模式',
        },{
            eleType: BaseFormItemEleType.BASESELECT,
            prop: 'labelPosition',
            value: null,            
            label: '表单域标签的位置',
            data: [
                {label:'left',value:'left'},
                {label:'right',value:'right'},
                {label:'top',value:'top'},
            ]
        },{
            eleType: BaseFormItemEleType.BASEINPUT,
            prop: 'labelWidth',
            value:null,
            label: '标签的长度',
        },{
            eleType: BaseFormItemEleType.BASEINPUT,
            prop: 'labelSuffix',
            value:null,
            label: '表单域标签的后缀',
        },{
            eleType: BaseFormItemEleType.BASESWITCH,
            prop: 'hideRequiredAsterisk',
            value:false,
            label: '是否隐藏必填字段标签旁边的红色星号',
        },{
            eleType: BaseFormItemEleType.BASESWITCH,
            prop: 'showMessage',
            value:true,
            label: '是否显示校验错误信息',
        },{
            eleType: BaseFormItemEleType.BASESWITCH,
            prop: 'inlineMessage',
            value:false,
            label: '是否以行内形式展示校验信息',
        },{
            eleType: BaseFormItemEleType.BASESWITCH,
            prop: 'statusIcon',
            value:false,
            label: '是否在输入框中显示校验结果反馈图标',
        },{
            eleType: BaseFormItemEleType.BASESWITCH,
            prop: 'validateOnRuleChange',
            value:true,
            label: '是否在 rules 属性改变后立即触发一次验证',
        },{
            eleType: BaseFormItemEleType.BASESWITCH,
            prop: 'scrollToError',
            value:false,
            label: '当校验失败时，滚动到第一个错误表单项',
        },
        {
            eleType: BaseFormItemEleType.BASESWITCH,
            prop: 'disabled',
            value:false,
            label: '禁用'
        },{
            eleType: BaseFormItemEleType.BASESELECT,
            prop: 'size',
            value:'',
            label: '尺寸',
            data: dictJson.sizes
        },{
            eleType: BaseFormItemEleType.BASEINPUT,
            prop: 'class',
            value:'',
            label: '类'
        },{
            eleType: BaseFormItemEleType.BASEINPUT,
            prop: 'style',
            value:'',
            label: '样式'
        },{
            eleType: BaseFormItemEleType.BASESWITCH,
            prop: 'validateEvent',
            value:true,
            label: '输入时是否触发表单的校验',
        }
    ]
})
const myForm=ref(null)

// 白名单（该属性默认为true）
const propsConfig=['validateEvent']
const useConfig = () => {
    if (myForm.value) {
        let newData = deepClone(myForm.value.newData)
        const dataKeys = Object.keys(newData)
        dataKeys.map(item => {
            if (!newData[item]&&!propsConfig.includes(item)) { 
                delete newData[item]
            }
        })
        if (Object.keys(newData).length > 0) {
            config.value = {...initData,...newData}
            refreshEditor.value = false
            nextTick(() => {
                refreshEditor.value = true
            })
        } else { 
            reset()
        }
    }
}
const reset = () => { 
    config.value = initData
    refreshEditor.value = false
    nextTick(() => {
        myForm.value.resetForm()
        refreshEditor.value = true
    })
}
// JsonEditor数据同步
const updateData = (e) => { 
    config.value=isRef(e)&&e.value||e
}
</script>
<style lang="scss" scoped>
    @import "../../assets/css/index.scss";
    :deep(.custom-title){
        line-height: 48px;
        background: #f8f9fa;
        font-size: 16px;
        font-weight: 400;
        color: #333;
        position: relative;
        padding-left: 16px;
        margin-bottom: 20px;
        &::before{
            content: "";
            position: absolute;
            width: 4px;
            height: 16px;
            background: #655eff;
            left: 6px;
            top: 16px;
        }
    }
    .btns{
        display: flex;
        justify-content: center;
    }
    .tip{
        color: #999;
        text-align: center;
        padding: 10px;
    }
    .btns{
        display: flex;
        justify-content: center;
    }
    .item-custom{padding:10px}
</style>